using System;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using System.Text;

namespace IWS.Lib.Utilities.Web
{
	public class FormControl : System.Web.UI.UserControl
	{
		public delegate void SaveEventHandler(object sender, SaveEventArgs e);
		protected bool IsInitialized;
		public FormControl()
			: base()
		{
			IsInitialized = false;
		}

		#region Custom Events
		private event SaveEventHandler eAfterSaveClick;
		private event EventHandler eSaveClick;
		private event EventHandler eBackClick;
		private event EventHandler eDeleteClick;

		/// <summary>
		/// Occurs when a save button is clicked.
		/// </summary>
		public event EventHandler SaveClick
		{
			add { eSaveClick += value; }
			remove { eSaveClick -= value; }
		}

		public event SaveEventHandler AfterSave
		{
			add { eAfterSaveClick += value; }
			remove {eAfterSaveClick -= value;}
		}
		/// <summary>
		/// Occurs when a back button is clicked.
		/// </summary>
		public event EventHandler BackClick
		{
			add { eBackClick += value; }
			remove { eBackClick -= value; }
		}
		/// <summary>
		/// Occurs when a delete button is clicked.
		/// </summary>
		public event EventHandler DeleteClick
		{
			add { eDeleteClick += value; }
			remove { eDeleteClick -= value; }
		}

		/// <summary>
		/// This funtion should be called after a save has been performed and a new id is assigned to the associated entity. The new id will be passed as an argument to the event subscriber. 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected virtual void OnAfterSave(object sender, SaveEventArgs e)
		{
			if (this.eAfterSaveClick != null)
				this.eAfterSaveClick(sender, e);
		}

		/// <summary>
		/// Fires off the parent's save click delegate. This should be invoked on successful validation after data operations have been performed. 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		/// <remarks>This function is typically called after data operations have been performed. It's meant to be a middle man operation control that will allow a parent page to perform an operation after a data operation has completed inside the user control. </remarks>
		protected virtual void OnSaveClick(object sender, EventArgs e)
		{
			if (this.eSaveClick != null)
			{
				this.eSaveClick(sender, e);
			}
		}
		/// <summary>
		/// Notifies a subscriber that a back click has been invoked. 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		/// <remarks>Typically this function is used indirectly through the BackClick event. For example a page subscribes to back click, then when the action happens inside a control, it passes the back click ot the page to allow back operations to happen. </remarks>
		protected virtual void OnBackClick(object sender, EventArgs e)
		{
			if (this.eBackClick != null)
			{
				this.eBackClick(sender, e);
			}
		}
		/// <summary>
		/// Fires off the parent's delete click delegate. This should be invoked after data operations have been performed. 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		/// <remarks>This function is typically called after data operations have been performed. It's meant to be a middle man operation control that will allow a parent page to perform an operation after a data operation has completed inside the user control. </remarks>
		protected virtual void OnDeleteClick(object sender, EventArgs e)
		{
			if (this.eDeleteClick != null)
			{
				this.eDeleteClick(sender, e);
			}
		}
		#endregion

		/// <summary>
		/// Initializes this class. 
		/// </summary>
		/// <remarks>This function is the primaty one intended for initialization. This one will call into InitializeCustom only once per postback. In Load functions, you should always call this function first to prevent running initialization code more than once. Override the InitializeCustom for custom implementation.</remarks>
		protected void Initialize()
		{
			if (!IsInitialized)
			{
				IsInitialized = true;
				this.InitializeCustom();
			}
		}

		/// <summary>
		/// Iimplementation of initialization goes here. 
		/// </summary>
		protected virtual void InitializeCustom()
		{
			//perform initialization code here. 
		}


		/// <summary>
		/// Log an exception to a logging utility. 
		/// </summary>
		/// <remarks>This function proxies the log functionality in case the logging library is changed in the future. Form controls should use this as their primary logging mechanism.</remarks>
		/// <param name="ex">Exception to log</param>
		/// <param name="ass">The assembly which the log originates. (Typically System.Reflection.Assembly.GetExecutingAssembly()).</param>
		protected void LogException(Exception ex, System.Reflection.Assembly assembly)
		{
			//TODO:	customer log info here
		}
		/// <summary>
		/// Change the current selection in a drop down to a new value.
		/// </summary>
		/// <param name="ddl"></param>
		/// <param name="value"></param>
		protected void SetDropDownListValue(DropDownList ddl, string value)
		{
			ListItem item = ddl.Items.FindByValue(value);
			if (item != null)
			{
				ddl.ClearSelection();
				item.Selected = true;
			}
		}
		protected void SetDropDownListData(DropDownList ddl, System.Collections.IEnumerable data, string text, string value)
		{
			ddl.DataSource = data;
			ddl.DataTextField = text;
			ddl.DataValueField = value;
			ddl.DataBind();
		}
		protected void SetDropDownListData(DropDownList ddl, Type enum_type)
		{
			ddl.Items.Clear();
			foreach (System.Enum eValue in Enum.GetValues(enum_type))
			{
				int value = Convert.ToInt32(eValue);
				ddl.Items.Add(new ListItem(eValue.ToString(), value.ToString()));
			}
		}

		protected string GetSelectedDropDownListValue(DropDownList ddl)
		{
			ListItem item = ddl.SelectedItem;
			if (item != null)
			{
				return item.Value;
			}
			return string.Empty;
		}

		protected virtual void HandleError(Exception ex)
		{

		}
	}

	public class SaveEventArgs : EventArgs
	{
		private object oNewID;

		public object NewID
		{
			get { return oNewID; }
			set { oNewID = value; }
		}
	

		public SaveEventArgs(object newid)
		{
			this.NewID = newid;
		}
	}
}
